﻿using Nop.Services.Logging;
using Nop.Services.Logistics;
using Nop.Services.Shipping.Tracking;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Spotshub.Plugin.Shipping.Spotshub
{
    public class SpotshubShipmentTracker : IShipmentTracker
    {
        private readonly ILogger _logger;
        private readonly ILogisticsService _logisticsService;

        public SpotshubShipmentTracker(ILogger logger, ILogisticsService logisticsService)
        {
            this._logger = logger;
            this._logisticsService = logisticsService;
        }

        /// <summary>
        /// Gets if the current tracker can track the tracking number.
        /// </summary>
        /// <param name="trackingNumber">The tracking number to track.</param>
        /// <returns>True if the tracker can track, otherwise false.</returns>
        public virtual bool IsMatch(string trackingNumber)
        {
            if (string.IsNullOrWhiteSpace(trackingNumber))
                return false;

            // Must update if the tracking number algorithm is changed.
            return System.Text.RegularExpressions.Regex.IsMatch(trackingNumber, "^[0-9][0-9][0-9][0-9][0-9]-[0-9]+");
        }

        /// <summary>
        /// Gets a url for a page to show tracking info (third party tracking page).
        /// </summary>
        /// <param name="trackingNumber">The tracking number to track.</param>
        /// <returns>A url to a tracking page.</returns>
        public virtual string GetUrl(string trackingNumber)
        {
            return null;
        }

        /// <summary>
        /// Gets all events for a tracking number.
        /// </summary>
        /// <param name="trackingNumber">The tracking number to track</param>
        /// <returns>List of Shipment Events.</returns>
        public virtual IList<ShipmentStatusEvent> GetShipmentEvents(string trackingNumber)
        {
            IList<ShipmentStatusEvent> result = new List<ShipmentStatusEvent>();

            try
            {
                var pkgs = this._logisticsService.SearchTrackingPackages
                    (0, null, null, trackingNumber, 0, int.MaxValue);
                var pkg = pkgs.FirstOrDefault(o => o.Shipment != null &&
                        o.Shipment.TrackingNumber.Equals(trackingNumber, StringComparison.OrdinalIgnoreCase));

                if (pkg != null)
                {
                    result = _logisticsService.GetPackageEvents(pkg, true);
                }
                else
                {
                    _logger.Error(string.Format("Error while getting spotshub shipment tracking info - {0}", trackingNumber));
                }
            }
            catch (Exception exc)
            {
                _logger.Error(string.Format("Error while getting spotshub shipment tracking info - {0}", trackingNumber), exc);
            }
            return result;
        }
    }
}